|
@ -1,35 +1,29 @@ |
|
|
--[[ |
|
|
|
|
|
Sothr Package Manager, browser and downloader, for easy access to many programs |
|
|
|
|
|
Author: Vexatos, WarrickSothr |
|
|
|
|
|
Forked and modified from: https://github.com/Wuerfel21/OpenComputers/blob/master/src/main/resources/assets/opencomputers/loot/OPPM/oppm.lua |
|
|
|
|
|
]] |
|
|
|
|
|
local component = require("component") |
|
|
|
|
|
local event = require("event") |
|
|
|
|
|
local fs = require("filesystem") |
|
|
|
|
|
local process = require("process") |
|
|
|
|
|
local serial = require("serialization") |
|
|
|
|
|
local shell = require("shell") |
|
|
|
|
|
local term = require("term") |
|
|
|
|
|
|
|
|
|
|
|
local wget = loadfile("/bin/wget.lua") |
|
|
|
|
|
|
|
|
|
|
|
local gpu = component.gpu |
|
|
|
|
|
|
|
|
|
|
|
if not component.isAvailable("internet") then |
|
|
|
|
|
io.stderr:write("This program requires an internet card to run.") |
|
|
|
|
|
|
|
|
component = require("component") |
|
|
|
|
|
event = require("event") |
|
|
|
|
|
fs = require("filesystem") |
|
|
|
|
|
process = require("process") |
|
|
|
|
|
serial = require("serialization") |
|
|
|
|
|
shell = require("shell") |
|
|
|
|
|
term = require("term") |
|
|
|
|
|
|
|
|
|
|
|
wget = loadfile("/bin/wget.lua") |
|
|
|
|
|
|
|
|
|
|
|
gpu = component.gpu |
|
|
|
|
|
|
|
|
|
|
|
if not component.isAvailable("internet") |
|
|
|
|
|
io.stderr\write("This program requires an internet card to run.") |
|
|
return |
|
|
return |
|
|
end |
|
|
|
|
|
local internet = require("internet") |
|
|
|
|
|
|
|
|
|
|
|
local githubContentRoot = "https://raw.githubusercontent.com/" |
|
|
|
|
|
local repoLocationConfig = "{URL_BASE}/repos.cfg" |
|
|
|
|
|
local localInstalledPackagesFile = "/etc/spdata.svd" |
|
|
|
|
|
local localConfigFile = "/etc/spm.cfg" |
|
|
|
|
|
|
|
|
internet = require("internet") |
|
|
|
|
|
|
|
|
local args, options = shell.parse(...) |
|
|
|
|
|
|
|
|
githubContentRoot = "https://raw.githubusercontent.com/" |
|
|
|
|
|
repoLocationConfig = "{URL_BASE}/repos.cfg" |
|
|
|
|
|
localInstalledPackagesFile = "/etc/spdata.svd" |
|
|
|
|
|
localConfigFile = "/etc/spm.cfg" |
|
|
|
|
|
|
|
|
|
|
|
args, options = shell.parse(...) |
|
|
|
|
|
|
|
|
local function printUsage() |
|
|
|
|
|
|
|
|
printUsage = -> |
|
|
print("Sothr Package Manager, use this to browse through and download sothr packaged programs easily") |
|
|
print("Sothr Package Manager, use this to browse through and download sothr packaged programs easily") |
|
|
print("Usage:") |
|
|
print("Usage:") |
|
|
print("'spm list [-i]' to get a list of all the available program packages") |
|
|
print("'spm list [-i]' to get a list of all the available program packages") |
|
@ -42,551 +36,458 @@ local function printUsage() |
|
|
print("'spm uninstall|remove <package>' to remove a package from your system") |
|
|
print("'spm uninstall|remove <package>' to remove a package from your system") |
|
|
print("'spm copy <package>' to copy package files to another location") |
|
|
print("'spm copy <package>' to copy package files to another location") |
|
|
print(" -f: Force creation of directories and overwriting of existing files.") |
|
|
print(" -f: Force creation of directories and overwriting of existing files.") |
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
-- Make an internet http/s request for data |
|
|
-- Make an internet http/s request for data |
|
|
local function getContent(url) |
|
|
|
|
|
local sContent = "" |
|
|
|
|
|
local result, response = pcall(internet.request, url) |
|
|
|
|
|
|
|
|
getContent = (url) -> |
|
|
|
|
|
sContent = "" |
|
|
|
|
|
result, response = pcall(internet.request, url) |
|
|
|
|
|
|
|
|
if not result then |
|
|
|
|
|
|
|
|
if not result |
|
|
return nil |
|
|
return nil |
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
for chunk in response do |
|
|
|
|
|
|
|
|
for chunk in response |
|
|
sContent = sContent .. chunk |
|
|
sContent = sContent .. chunk |
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
return sContent |
|
|
return sContent |
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
-- Request repository information |
|
|
-- Request repository information |
|
|
local function getRepos() |
|
|
|
|
|
local success, sRepos = pcall(getContent, repoLocationConfig) |
|
|
|
|
|
|
|
|
getRepos -> |
|
|
|
|
|
success, sRepos = pcall(getContent, repoLocationConfig) |
|
|
|
|
|
|
|
|
if not success then |
|
|
|
|
|
io.stderr:write("Could not connect to the Internet. Please ensure you have an Internet connection.") |
|
|
|
|
|
|
|
|
if not success |
|
|
|
|
|
io.stderr\write("Could not connect to the Internet. Please ensure you have an Internet connection.") |
|
|
return -1 |
|
|
return -1 |
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
return serial.unserialize(sRepos) |
|
|
return serial.unserialize(sRepos) |
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
-- Get Packages for src |
|
|
-- Get Packages for src |
|
|
local function getPackages(src) |
|
|
|
|
|
local success, sPackages = pcall(getContent, src .. "/programs.cfg") |
|
|
|
|
|
|
|
|
getPackages = (src) -> |
|
|
|
|
|
success, sPackages = pcall(getContent, src .. "/programs.cfg") |
|
|
|
|
|
|
|
|
if not success or not sPackages then |
|
|
|
|
|
|
|
|
if not success or not sPackages |
|
|
return -1 |
|
|
return -1 |
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
return serial.unserialize(sPackages) |
|
|
return serial.unserialize(sPackages) |
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
local function getGithubPackages(repo) |
|
|
|
|
|
|
|
|
getGithubPackages = (repo) -> |
|
|
return getPackages(githubContentRoot .. repo .. "/master") |
|
|
return getPackages(githubContentRoot .. repo .. "/master") |
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
--For sorting table values by alphabet |
|
|
--For sorting table values by alphabet |
|
|
local function compare(a, b) |
|
|
|
|
|
for i = 1, math.min(#a, #b) do |
|
|
|
|
|
if a:sub(i, i) ~= b:sub(i, i) then |
|
|
|
|
|
|
|
|
compare = (a, b) -> |
|
|
|
|
|
for i = 1, math.min(#a, #b) |
|
|
|
|
|
if a:sub(i, i) ~= b:sub(i, i) |
|
|
return a:sub(i, i) < b:sub(i, i) |
|
|
return a:sub(i, i) < b:sub(i, i) |
|
|
end |
|
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
return #a < #b |
|
|
return #a < #b |
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
local function downloadFile(url, path, force) |
|
|
|
|
|
if options.f or force then |
|
|
|
|
|
|
|
|
downloadFile = (url, path, force) -> |
|
|
|
|
|
if options.f or force |
|
|
wget("-fq", url, path) |
|
|
wget("-fq", url, path) |
|
|
else |
|
|
else |
|
|
wget("-q", url, path) |
|
|
wget("-q", url, path) |
|
|
end |
|
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
local function readFromFile(path) |
|
|
|
|
|
if not fs.exists(fs.path(path)) then |
|
|
|
|
|
|
|
|
readFromFile = (path) -> |
|
|
|
|
|
if not fs.exists(fs.path(path)) |
|
|
fs.makeDirectory(fs.path(path)) |
|
|
fs.makeDirectory(fs.path(path)) |
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
if not fs.exists(path) then |
|
|
|
|
|
|
|
|
if not fs.exists(path) |
|
|
return { -1 } |
|
|
return { -1 } |
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
local file, msg = io.open(path, "rb") |
|
|
|
|
|
if not file then |
|
|
|
|
|
io.stderr:write("Error while trying to read file at " .. path .. ": " .. msg) |
|
|
|
|
|
|
|
|
file, msg = io.open(path, "rb") |
|
|
|
|
|
if not file |
|
|
|
|
|
io.stderr\write("Error while trying to read file at " .. path .. ": " .. msg) |
|
|
return |
|
|
return |
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
local serializedTableData = file:read("*a") |
|
|
|
|
|
|
|
|
serializedTableData = file:read("*a") |
|
|
file:close() |
|
|
file:close() |
|
|
return serial.unserialize(serializedTableData) or { -1 } |
|
|
return serial.unserialize(serializedTableData) or { -1 } |
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
local function readFromLocalInstallFile() |
|
|
|
|
|
|
|
|
readFromLocalInstallFile = -> |
|
|
return readFromFile(localInstalledPackagesFile) |
|
|
return readFromFile(localInstalledPackagesFile) |
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
local function readLocalConfigFile() |
|
|
|
|
|
local path = localConfigFile |
|
|
|
|
|
if not fs.exists(path) then |
|
|
|
|
|
|
|
|
readLocalConfigFile = -> |
|
|
|
|
|
path = localConfigFile |
|
|
|
|
|
if not fs.exists(path) |
|
|
return { -1 } |
|
|
return { -1 } |
|
|
else |
|
|
else |
|
|
return readFromFile(path) |
|
|
return readFromFile(path) |
|
|
end |
|
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
local function saveToInstalledPackagesFile(installedPackages) |
|
|
|
|
|
|
|
|
saveToInstalledPackagesFile = (installedPackages) -> |
|
|
|
|
|
|
|
|
local file, msg = io.open(localInstalledPackagesFile, "wb") |
|
|
|
|
|
|
|
|
file, msg = io.open(localInstalledPackagesFile, "wb") |
|
|
|
|
|
|
|
|
if not file then |
|
|
|
|
|
io.stderr:write("Error while trying to save package names: " .. msg) |
|
|
|
|
|
|
|
|
if not file |
|
|
|
|
|
io.stderr\write("Error while trying to save package names: " .. msg) |
|
|
return |
|
|
return |
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
local sPacks = serial.serialize(installedPackages) |
|
|
|
|
|
|
|
|
sPacks = serial.serialize(installedPackages) |
|
|
file:write(sPacks) |
|
|
file:write(sPacks) |
|
|
file:close() |
|
|
file:close() |
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
local function listPackages(filter) |
|
|
|
|
|
|
|
|
listPackages = (filter) -> |
|
|
filter = filter or false |
|
|
filter = filter or false |
|
|
|
|
|
|
|
|
if filter then |
|
|
|
|
|
|
|
|
if filter |
|
|
filter = string.lower(filter) |
|
|
filter = string.lower(filter) |
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
local packageTable = {} |
|
|
|
|
|
|
|
|
packageTable = {} |
|
|
print("Receiving Package list...") |
|
|
print("Receiving Package list...") |
|
|
if not options.i then |
|
|
|
|
|
local success, repositories = pcall(getRepos) |
|
|
|
|
|
|
|
|
if not options.i |
|
|
|
|
|
success, repositories = pcall(getRepos) |
|
|
|
|
|
|
|
|
if not success or repositories == -1 then |
|
|
|
|
|
io.stderr:write("Unable to connect to the Internet.\n") |
|
|
|
|
|
|
|
|
if not success or repositories == -1 |
|
|
|
|
|
io.stderr\write("Unable to connect to the Internet.\n") |
|
|
return |
|
|
return |
|
|
elseif repositories == nil then |
|
|
|
|
|
|
|
|
elseif repositories == nil |
|
|
print("Error while trying to receive repository list") |
|
|
print("Error while trying to receive repository list") |
|
|
return |
|
|
return |
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
for _, repository in pairs(repositories) do |
|
|
|
|
|
local packages |
|
|
|
|
|
local target |
|
|
|
|
|
|
|
|
for _, repository in pairs(repositories) |
|
|
|
|
|
packages |
|
|
|
|
|
target |
|
|
|
|
|
|
|
|
if repository.src then |
|
|
|
|
|
|
|
|
if repository.src |
|
|
print("Checking Repository " .. repository.src) |
|
|
print("Checking Repository " .. repository.src) |
|
|
packages = getPackages(repository.src) |
|
|
packages = getPackages(repository.src) |
|
|
target = repository.src |
|
|
target = repository.src |
|
|
elseif repository.repo then |
|
|
|
|
|
|
|
|
elseif repository.repo |
|
|
print("Checking Repository " .. repository.repo) |
|
|
print("Checking Repository " .. repository.repo) |
|
|
packages = getGithubPackages(repository.repo) |
|
|
packages = getGithubPackages(repository.repo) |
|
|
target = repository.repo |
|
|
target = repository.repo |
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
if packages == nil then |
|
|
|
|
|
io.stderr:write("Error while trying to receive package list for " .. target .. "\n") |
|
|
|
|
|
|
|
|
if packages == nil |
|
|
|
|
|
io.stderr\write("Error while trying to receive package list for " .. target .. "\n") |
|
|
return |
|
|
return |
|
|
elseif type(packages) == "table" then |
|
|
|
|
|
for package in pairs(packages) do |
|
|
|
|
|
if not package.hidden then |
|
|
|
|
|
|
|
|
elseif type(packages) == "table" |
|
|
|
|
|
for package in pairs(packages) |
|
|
|
|
|
if not package.hidden |
|
|
table.insert(packageTable, package) |
|
|
table.insert(packageTable, package) |
|
|
end |
|
|
|
|
|
end |
|
|
|
|
|
end |
|
|
|
|
|
end |
|
|
|
|
|
else |
|
|
else |
|
|
local localPackageTable = {} |
|
|
|
|
|
local localPackages = readFromLocalInstallFile() |
|
|
|
|
|
for localPackage in pairs(localPackages) do |
|
|
|
|
|
|
|
|
localPackageTable = {} |
|
|
|
|
|
localPackages = readFromLocalInstallFile() |
|
|
|
|
|
for localPackage in pairs(localPackages) |
|
|
table.insert(localPackageTable, localPackage) |
|
|
table.insert(localPackageTable, localPackage) |
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
packageTable = localPackageTable |
|
|
packageTable = localPackageTable |
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
if filter then |
|
|
|
|
|
local packages = {} |
|
|
|
|
|
for _, package in ipairs(packageTable) do |
|
|
|
|
|
if (#package >= #filter) and string.find(package, filter, 1, true) ~= nil then |
|
|
|
|
|
|
|
|
if filter |
|
|
|
|
|
packages = {} |
|
|
|
|
|
for _, package in ipairs(packageTable) |
|
|
|
|
|
if (#package >= #filter) and string.find(package, filter, 1, true) ~= nil |
|
|
table.insert(packages, package) |
|
|
table.insert(packages, package) |
|
|
end |
|
|
|
|
|
end |
|
|
|
|
|
packageTable = packages |
|
|
packageTable = packages |
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
table.sort(packageTable, compare) |
|
|
table.sort(packageTable, compare) |
|
|
return packageTable |
|
|
return packageTable |
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
local function printPackages(packages) |
|
|
|
|
|
|
|
|
printPackages = (packages) -> |
|
|
|
|
|
|
|
|
if packages == nil or not packages[1] then |
|
|
|
|
|
|
|
|
if packages == nil or not packages[1] |
|
|
print("No package matching specified filter found.") |
|
|
print("No package matching specified filter found.") |
|
|
return |
|
|
return |
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
term.clear() |
|
|
term.clear() |
|
|
local xRes, yRes = gpu.getResolution() |
|
|
|
|
|
|
|
|
xRes, yRes = gpu.getResolution() |
|
|
print("--SPM {ENV} Package list--") |
|
|
print("--SPM {ENV} Package list--") |
|
|
local xCur, yCur = term.getCursor() |
|
|
|
|
|
for _, package in ipairs(packages) do |
|
|
|
|
|
|
|
|
xCur, yCur = term.getCursor() |
|
|
|
|
|
for _, package in ipairs(packages) |
|
|
term.write(package .. "\n") |
|
|
term.write(package .. "\n") |
|
|
yCur = yCur + 1 |
|
|
yCur = yCur + 1 |
|
|
if yCur > yRes - 1 then |
|
|
|
|
|
|
|
|
if yCur > yRes - 1 |
|
|
term.write("[Press any key to continue]") |
|
|
term.write("[Press any key to continue]") |
|
|
local event = event.pull("key_down") |
|
|
|
|
|
if event then |
|
|
|
|
|
|
|
|
event = event.pull("key_down") |
|
|
|
|
|
if event |
|
|
term.clear() |
|
|
term.clear() |
|
|
print("--SPM {ENV} Package list--") |
|
|
print("--SPM {ENV} Package list--") |
|
|
xCur, yCur = term.getCursor() |
|
|
xCur, yCur = term.getCursor() |
|
|
end |
|
|
|
|
|
end |
|
|
|
|
|
end |
|
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
local function getInformation(requestedPackage) |
|
|
|
|
|
local success, repositories = pcall(getRepos) |
|
|
|
|
|
|
|
|
getInformation = (requestedPackage) -> |
|
|
|
|
|
success, repositories = pcall(getRepos) |
|
|
|
|
|
|
|
|
if not success or repositories == -1 then |
|
|
|
|
|
io.stderr:write("Unable to connect to the Internet.\n") |
|
|
|
|
|
|
|
|
if not success or repositories == -1 |
|
|
|
|
|
io.stderr\write("Unable to connect to the Internet.\n") |
|
|
return |
|
|
return |
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
for _, repository in pairs(repositories) do |
|
|
|
|
|
local packages |
|
|
|
|
|
local target |
|
|
|
|
|
|
|
|
for _, repository in pairs(repositories) |
|
|
|
|
|
packages |
|
|
|
|
|
target |
|
|
|
|
|
|
|
|
if repository.src then |
|
|
|
|
|
|
|
|
if repository.src |
|
|
packages = getPackages(repository.src) |
|
|
packages = getPackages(repository.src) |
|
|
target = repository.src |
|
|
target = repository.src |
|
|
elseif repository.repo then |
|
|
|
|
|
|
|
|
elseif repository.repo |
|
|
packages = getGithubPackages(repository.repo) |
|
|
packages = getGithubPackages(repository.repo) |
|
|
target = githubContentRoot .. repository.repo |
|
|
target = githubContentRoot .. repository.repo |
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
if packages == nil then |
|
|
|
|
|
io.stderr:write("Error while trying to receive package list for " .. target .. "\n") |
|
|
|
|
|
elseif type(packages) == "table" then |
|
|
|
|
|
for package in pairs(packages) do |
|
|
|
|
|
if package == requestedPackage then |
|
|
|
|
|
|
|
|
if packages == nil |
|
|
|
|
|
io.stderr\write("Error while trying to receive package list for " .. target .. "\n") |
|
|
|
|
|
elseif type(packages) == "table" |
|
|
|
|
|
for package in pairs(packages) |
|
|
|
|
|
if package == requestedPackage |
|
|
return packages[package], target |
|
|
return packages[package], target |
|
|
end |
|
|
|
|
|
end |
|
|
|
|
|
end |
|
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
return nil |
|
|
return nil |
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
local function provideInfo(pack) |
|
|
|
|
|
if not pack then |
|
|
|
|
|
|
|
|
provideInfo = (pack) -> |
|
|
|
|
|
if not pack |
|
|
printUsage() |
|
|
printUsage() |
|
|
return |
|
|
return |
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
pack = string.lower(pack) |
|
|
pack = string.lower(pack) |
|
|
local info = getInformation(pack) |
|
|
|
|
|
if not info then |
|
|
|
|
|
|
|
|
info = getInformation(pack) |
|
|
|
|
|
if not info |
|
|
print("Package does not exist") |
|
|
print("Package does not exist") |
|
|
return |
|
|
return |
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
local done = false |
|
|
|
|
|
|
|
|
done = false |
|
|
print("--Information about package '" .. pack .. "'--") |
|
|
print("--Information about package '" .. pack .. "'--") |
|
|
if info.name then |
|
|
|
|
|
|
|
|
if info.name |
|
|
print("Name: " .. info.name) |
|
|
print("Name: " .. info.name) |
|
|
done = true |
|
|
done = true |
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
if info.version then |
|
|
|
|
|
|
|
|
if info.version |
|
|
print("Version: " .. info.version) |
|
|
print("Version: " .. info.version) |
|
|
done = true |
|
|
done = true |
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
if info.description then |
|
|
|
|
|
|
|
|
if info.description |
|
|
print("Description: " .. info.description) |
|
|
print("Description: " .. info.description) |
|
|
done = true |
|
|
done = true |
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
if info.authors then |
|
|
|
|
|
|
|
|
if info.authors |
|
|
print("Authors: " .. info.authors) |
|
|
print("Authors: " .. info.authors) |
|
|
done = true |
|
|
done = true |
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
if info.note then |
|
|
|
|
|
|
|
|
if info.note |
|
|
print("Note: " .. info.note) |
|
|
print("Note: " .. info.note) |
|
|
done = true |
|
|
done = true |
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
if not done then |
|
|
|
|
|
|
|
|
if not done |
|
|
print("No information provided.") |
|
|
print("No information provided.") |
|
|
end |
|
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
local function installPackage(requestedPackage, installPath, doUpdate) |
|
|
|
|
|
|
|
|
installPackage = (requestedPackage, installPath, doUpdate) -> |
|
|
doUpdate = doUpdate or false |
|
|
doUpdate = doUpdate or false |
|
|
|
|
|
|
|
|
if not requestedPackage then |
|
|
|
|
|
|
|
|
if not requestedPackage |
|
|
printUsage() |
|
|
printUsage() |
|
|
return |
|
|
return |
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
if not installPath and not doUpdate then |
|
|
|
|
|
local localConfig = readLocalConfigFile() |
|
|
|
|
|
|
|
|
if not installPath and not doUpdate |
|
|
|
|
|
localConfig = readLocalConfigFile() |
|
|
installPath = localConfig.path or "/usr" |
|
|
installPath = localConfig.path or "/usr" |
|
|
print("Installing package to " .. installPath .. "...") |
|
|
print("Installing package to " .. installPath .. "...") |
|
|
elseif not doUpdate then |
|
|
|
|
|
|
|
|
elseif not doUpdate |
|
|
installPath = shell.resolve(installPath) |
|
|
installPath = shell.resolve(installPath) |
|
|
print("Installing package to " .. installPath .. "...") |
|
|
print("Installing package to " .. installPath .. "...") |
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
requestedPackage = string.lower(requestedPackage) |
|
|
requestedPackage = string.lower(requestedPackage) |
|
|
|
|
|
|
|
|
local locallyInstalledPackages = readFromLocalInstallFile() |
|
|
|
|
|
|
|
|
locallyInstalledPackages = readFromLocalInstallFile() |
|
|
|
|
|
|
|
|
if not locallyInstalledPackages then |
|
|
|
|
|
io.stderr:write("Error while trying to read local package names") |
|
|
|
|
|
|
|
|
if not locallyInstalledPackages |
|
|
|
|
|
io.stderr\write("Error while trying to read local package names") |
|
|
return |
|
|
return |
|
|
elseif locallyInstalledPackages[1] == -1 then |
|
|
|
|
|
|
|
|
elseif locallyInstalledPackages[1] == -1 |
|
|
table.remove(locallyInstalledPackages, 1) |
|
|
table.remove(locallyInstalledPackages, 1) |
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
local packageInfo, repositoryPath = getInformation(requestedPackage) |
|
|
|
|
|
if not packageInfo then |
|
|
|
|
|
|
|
|
packageInfo, repositoryPath = getInformation(requestedPackage) |
|
|
|
|
|
if not packageInfo |
|
|
print("Package does not exist") |
|
|
print("Package does not exist") |
|
|
return |
|
|
return |
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
if doUpdate then |
|
|
|
|
|
|
|
|
if doUpdate |
|
|
print("Updating package " .. requestedPackage) |
|
|
print("Updating package " .. requestedPackage) |
|
|
installPath = nil |
|
|
installPath = nil |
|
|
for filePath, fileInstallPath in pairs(packageInfo.files) do |
|
|
|
|
|
for installedFilePath, fileLocalInstallPath in pairs(locallyInstalledPackages[requestedPackage]) do |
|
|
|
|
|
if installedFilePath == filePath then |
|
|
|
|
|
|
|
|
for filePath, fileInstallPath in pairs(packageInfo.files) |
|
|
|
|
|
for installedFilePath, fileLocalInstallPath in pairs(locallyInstalledPackages[requestedPackage]) |
|
|
|
|
|
if installedFilePath == filePath |
|
|
installPath = string.gsub(fs.path(fileLocalInstallPath), fileInstallPath .. "/?$", "/") |
|
|
installPath = string.gsub(fs.path(fileLocalInstallPath), fileInstallPath .. "/?$", "/") |
|
|
break |
|
|
break |
|
|
end |
|
|
|
|
|
end |
|
|
|
|
|
if installPath then |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if installPath |
|
|
break |
|
|
break |
|
|
end |
|
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
installPath = shell.resolve(string.gsub(installPath, "^/?", "/"), nil) |
|
|
installPath = shell.resolve(string.gsub(installPath, "^/?", "/"), nil) |
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
if not doUpdate and fs.exists(installPath) then |
|
|
|
|
|
if not fs.isDirectory(installPath) then |
|
|
|
|
|
if options.f then |
|
|
|
|
|
|
|
|
if not doUpdate and fs.exists(installPath) |
|
|
|
|
|
if not fs.isDirectory(installPath) |
|
|
|
|
|
if options.f |
|
|
installPath = fs.concat(fs.path(installPath), requestedPackage) |
|
|
installPath = fs.concat(fs.path(installPath), requestedPackage) |
|
|
fs.makeDirectory(installPath) |
|
|
fs.makeDirectory(installPath) |
|
|
else |
|
|
else |
|
|
print("Path points to a file, needs to be a directory.") |
|
|
print("Path points to a file, needs to be a directory.") |
|
|
return |
|
|
return |
|
|
end |
|
|
|
|
|
end |
|
|
|
|
|
elseif not doUpdate then |
|
|
|
|
|
if options.f then |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
elseif not doUpdate |
|
|
|
|
|
if options.f |
|
|
fs.makeDirectory(installPath) |
|
|
fs.makeDirectory(installPath) |
|
|
else |
|
|
else |
|
|
print("Directory does not exist.") |
|
|
print("Directory does not exist.") |
|
|
return |
|
|
return |
|
|
end |
|
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
if locallyInstalledPackages[requestedPackage] and (not doUpdate) then |
|
|
|
|
|
|
|
|
if locallyInstalledPackages[requestedPackage] and (not doUpdate) |
|
|
print("Package has already been installed") |
|
|
print("Package has already been installed") |
|
|
return |
|
|
return |
|
|
elseif not locallyInstalledPackages[requestedPackage] and doUpdate then |
|
|
|
|
|
|
|
|
elseif not locallyInstalledPackages[requestedPackage] and doUpdate |
|
|
print("Package has not been installed.") |
|
|
print("Package has not been installed.") |
|
|
print("If it has, uninstall it manually and reinstall it.") |
|
|
print("If it has, uninstall it manually and reinstall it.") |
|
|
return |
|
|
return |
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
if doUpdate then |
|
|
|
|
|
|
|
|
if doUpdate |
|
|
term.write("Removing old files...") |
|
|
term.write("Removing old files...") |
|
|
for installedFilePath, fileLocalInstallPath in pairs(locallyInstalledPackages[requestedPackage]) do |
|
|
|
|
|
|
|
|
for installedFilePath, fileLocalInstallPath in pairs(locallyInstalledPackages[requestedPackage]) |
|
|
fs.remove(fileLocalInstallPath) |
|
|
fs.remove(fileLocalInstallPath) |
|
|
end |
|
|
|
|
|
term.write("Done.\n") |
|
|
term.write("Done.\n") |
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
locallyInstalledPackages[requestedPackage] = {} |
|
|
locallyInstalledPackages[requestedPackage] = {} |
|
|
term.write("Installing Files...") |
|
|
term.write("Installing Files...") |
|
|
for filePath, requestedInstallPath in pairs(packageInfo.files) do |
|
|
|
|
|
local installedPath |
|
|
|
|
|
|
|
|
for filePath, requestedInstallPath in pairs(packageInfo.files) |
|
|
|
|
|
installedPath |
|
|
|
|
|
|
|
|
if string.find(requestedInstallPath, "^//") then |
|
|
|
|
|
local localInstalledPath = string.sub(requestedInstallPath, 2) |
|
|
|
|
|
if not fs.exists(localInstalledPath) then |
|
|
|
|
|
|
|
|
if string.find(requestedInstallPath, "^//") |
|
|
|
|
|
localInstalledPath = string.sub(requestedInstallPath, 2) |
|
|
|
|
|
if not fs.exists(localInstalledPath) |
|
|
fs.makeDirectory(localInstalledPath) |
|
|
fs.makeDirectory(localInstalledPath) |
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
installedPath = fs.concat(localInstalledPath, string.gsub(filePath, ".+(/.-)$", "%1"), nil) |
|
|
installedPath = fs.concat(localInstalledPath, string.gsub(filePath, ".+(/.-)$", "%1"), nil) |
|
|
else |
|
|
else |
|
|
local localInstalledPath = fs.concat(installPath, requestedInstallPath) |
|
|
|
|
|
if not fs.exists(localInstalledPath) then |
|
|
|
|
|
|
|
|
localInstalledPath = fs.concat(installPath, requestedInstallPath) |
|
|
|
|
|
if not fs.exists(localInstalledPath) |
|
|
fs.makeDirectory(localInstalledPath) |
|
|
fs.makeDirectory(localInstalledPath) |
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
installedPath = fs.concat(installPath, requestedInstallPath, string.gsub(filePath, ".+(/.-)$", "%1"), nil) |
|
|
installedPath = fs.concat(installPath, requestedInstallPath, string.gsub(filePath, ".+(/.-)$", "%1"), nil) |
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
local downloadPath |
|
|
|
|
|
if (packageInfo.minified or options.m) and not options.nm then |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
downloadPath |
|
|
|
|
|
if (packageInfo.minified or options.m) and not options.nm |
|
|
downloadPath = repositoryPath .. "/" .. string.gsub(filePath, "(.+)%.lua$", "%1") .. ".min.lua" |
|
|
downloadPath = repositoryPath .. "/" .. string.gsub(filePath, "(.+)%.lua$", "%1") .. ".min.lua" |
|
|
else |
|
|
else |
|
|
downloadPath = repositoryPath .. "/" .. filePath |
|
|
downloadPath = repositoryPath .. "/" .. filePath |
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
local success = pcall(downloadFile, downloadPath, installedPath) |
|
|
|
|
|
if success then |
|
|
|
|
|
|
|
|
success = pcall(downloadFile, downloadPath, installedPath) |
|
|
|
|
|
if success |
|
|
locallyInstalledPackages[requestedPackage][filePath] = installedPath |
|
|
locallyInstalledPackages[requestedPackage][filePath] = installedPath |
|
|
end |
|
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
if packageInfo.dependencies then |
|
|
|
|
|
|
|
|
if packageInfo.dependencies |
|
|
term.write("Done.\nInstalling Dependencies...") |
|
|
term.write("Done.\nInstalling Dependencies...") |
|
|
for packageDependency, dependencyPath in pairs(packageInfo.dependencies) do |
|
|
|
|
|
local installedDependencyPath |
|
|
|
|
|
|
|
|
for packageDependency, dependencyPath in pairs(packageInfo.dependencies) |
|
|
|
|
|
installedDependencyPath |
|
|
|
|
|
|
|
|
if string.find(dependencyPath, "^//") then |
|
|
|
|
|
|
|
|
if string.find(dependencyPath, "^//") |
|
|
installedDependencyPath = string.sub(dependencyPath, 2) |
|
|
installedDependencyPath = string.sub(dependencyPath, 2) |
|
|
else |
|
|
else |
|
|
installedDependencyPath = fs.concat(installPath, dependencyPath, string.gsub(packageDependency, ".+(/.-)$", "%1"), nil) |
|
|
installedDependencyPath = fs.concat(installPath, dependencyPath, string.gsub(packageDependency, ".+(/.-)$", "%1"), nil) |
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
if string.lower(string.sub(packageDependency, 1, 4)) == "http" then |
|
|
|
|
|
local success = pcall(downloadFile, packageDependency, installedDependencyPath) |
|
|
|
|
|
if success then |
|
|
|
|
|
|
|
|
if string.lower(string.sub(packageDependency, 1, 4)) == "http" |
|
|
|
|
|
success = pcall(downloadFile, packageDependency, installedDependencyPath) |
|
|
|
|
|
if success |
|
|
locallyInstalledPackages[requestedPackage][packageDependency] = installedDependencyPath |
|
|
locallyInstalledPackages[requestedPackage][packageDependency] = installedDependencyPath |
|
|
end |
|
|
|
|
|
else |
|
|
else |
|
|
local dependencyInfo = getInformation(string.lower(packageDependency)) |
|
|
|
|
|
if not dependencyInfo then |
|
|
|
|
|
|
|
|
dependencyInfo = getInformation(string.lower(packageDependency)) |
|
|
|
|
|
if not dependencyInfo |
|
|
term.write("\nDependency package " .. packageDependency .. " does not exist.") |
|
|
term.write("\nDependency package " .. packageDependency .. " does not exist.") |
|
|
end |
|
|
|
|
|
installPackage(string.lower(packageDependency), fs.concat(installPath, dependencyPath)) |
|
|
installPackage(string.lower(packageDependency), fs.concat(installPath, dependencyPath)) |
|
|
end |
|
|
|
|
|
end |
|
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
term.write("Done.\n") |
|
|
term.write("Done.\n") |
|
|
saveToInstalledPackagesFile(locallyInstalledPackages) |
|
|
saveToInstalledPackagesFile(locallyInstalledPackages) |
|
|
print("Successfully installed package " .. requestedPackage) |
|
|
print("Successfully installed package " .. requestedPackage) |
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
local function copyPackage(requestedPackage, copyLocation) |
|
|
|
|
|
local packageInformation, repositoryLocation = getInformation(requestedPackage) |
|
|
|
|
|
if not packageInformation then |
|
|
|
|
|
|
|
|
copyPackage = (requestedPackage, copyLocation) -> |
|
|
|
|
|
packageInformation, repositoryLocation = getInformation(requestedPackage) |
|
|
|
|
|
if not packageInformation |
|
|
print("Package does not exist") |
|
|
print("Package does not exist") |
|
|
return |
|
|
return |
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
local locallyInstalledFiles = readFromLocalInstallFile() |
|
|
|
|
|
if not locallyInstalledFiles then |
|
|
|
|
|
io.stderr:write("Error while trying to read package names") |
|
|
|
|
|
|
|
|
locallyInstalledFiles = readFromLocalInstallFile() |
|
|
|
|
|
if not locallyInstalledFiles |
|
|
|
|
|
io.stderr\write("Error while trying to read package names") |
|
|
return |
|
|
return |
|
|
elseif locallyInstalledFiles[1] == -1 then |
|
|
|
|
|
|
|
|
elseif locallyInstalledFiles[1] == -1 |
|
|
table.remove(locallyInstalledFiles, 1) |
|
|
table.remove(locallyInstalledFiles, 1) |
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
if not locallyInstalledFiles[requestedPackage] then |
|
|
|
|
|
|
|
|
if not locallyInstalledFiles[requestedPackage] |
|
|
print("Package has not been installed.") |
|
|
print("Package has not been installed.") |
|
|
print("It must be installed to be copied.") |
|
|
print("It must be installed to be copied.") |
|
|
return |
|
|
return |
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
term.write("Copying package files...") |
|
|
term.write("Copying package files...") |
|
|
for installedFilePath, fileLocalInstallPath in pairs(locallyInstalledFiles[requestedPackage]) do |
|
|
|
|
|
|
|
|
for installedFilePath, fileLocalInstallPath in pairs(locallyInstalledFiles[requestedPackage]) |
|
|
fs.copy(fileLocalInstallPath, copyLocation .. fileLocalInstallPath) |
|
|
fs.copy(fileLocalInstallPath, copyLocation .. fileLocalInstallPath) |
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
if packageInfo.dependencies then |
|
|
|
|
|
|
|
|
if packageInfo.dependencies |
|
|
term.write("Done\nCopying Dependencies...") |
|
|
term.write("Done\nCopying Dependencies...") |
|
|
for packageDependency, _ in pairs(packageInfo.dependencies) do |
|
|
|
|
|
if not locallyInstalledFiles[packageDependency] then |
|
|
|
|
|
|
|
|
for packageDependency, _ in pairs(packageInfo.dependencies) |
|
|
|
|
|
if not locallyInstalledFiles[packageDependency] |
|
|
print("Dependency has not been installed.") |
|
|
print("Dependency has not been installed.") |
|
|
print("If it has, it is not recognized. Reinstall the parent package: " .. requestedPackage) |
|
|
print("If it has, it is not recognized. Reinstall the parent package: " .. requestedPackage) |
|
|
return |
|
|
return |
|
|
end |
|
|
|
|
|
copyPackage(packageDependency, copyLocation) |
|
|
copyPackage(packageDependency, copyLocation) |
|
|
end |
|
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
term.write("Done.\n") |
|
|
term.write("Done.\n") |
|
|
print("Successfully copied package " .. requestedPackage) |
|
|
print("Successfully copied package " .. requestedPackage) |
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
local function uninstallPackage(requestedPackage) |
|
|
|
|
|
local packageInformation, repositoryLocation = getInformation(requestedPackage) |
|
|
|
|
|
if not packageInformation then |
|
|
|
|
|
|
|
|
uninstallPackage = (requestedPackage) -> |
|
|
|
|
|
packageInformation, repositoryLocation = getInformation(requestedPackage) |
|
|
|
|
|
if not packageInformation |
|
|
print("Package does not exist") |
|
|
print("Package does not exist") |
|
|
return |
|
|
return |
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
local locallyInstalledFiles = readFromLocalInstallFile() |
|
|
|
|
|
if not locallyInstalledFiles then |
|
|
|
|
|
io.stderr:write("Error while trying to read package names") |
|
|
|
|
|
|
|
|
locallyInstalledFiles = readFromLocalInstallFile() |
|
|
|
|
|
if not locallyInstalledFiles |
|
|
|
|
|
io.stderr\write("Error while trying to read package names") |
|
|
return |
|
|
return |
|
|
elseif locallyInstalledFiles[1] == -1 then |
|
|
|
|
|
|
|
|
elseif locallyInstalledFiles[1] == -1 |
|
|
table.remove(locallyInstalledFiles, 1) |
|
|
table.remove(locallyInstalledFiles, 1) |
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
if not locallyInstalledFiles[requestedPackage] then |
|
|
|
|
|
|
|
|
if not locallyInstalledFiles[requestedPackage] |
|
|
print("Package has not been installed.") |
|
|
print("Package has not been installed.") |
|
|
print("If it has, you have to remove it manually.") |
|
|
print("If it has, you have to remove it manually.") |
|
|
return |
|
|
return |
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
term.write("Removing package files...") |
|
|
term.write("Removing package files...") |
|
|
for installedFilePath, fileLocalInstallPath in pairs(locallyInstalledFiles[requestedPackage]) do |
|
|
|
|
|
|
|
|
for installedFilePath, fileLocalInstallPath in pairs(locallyInstalledFiles[requestedPackage]) |
|
|
fs.remove(fileLocalInstallPath) |
|
|
fs.remove(fileLocalInstallPath) |
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
term.write("Done\nRemoving references...") |
|
|
term.write("Done\nRemoving references...") |
|
|
locallyInstalledFiles[requestedPackage] = nil |
|
|
locallyInstalledFiles[requestedPackage] = nil |
|
|
saveToInstalledPackagesFile(locallyInstalledFiles) |
|
|
saveToInstalledPackagesFile(locallyInstalledFiles) |
|
|
term.write("Done.\n") |
|
|
term.write("Done.\n") |
|
|
print("Successfully uninstalled package " .. requestedPackage) |
|
|
print("Successfully uninstalled package " .. requestedPackage) |
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
local function updatePackage(requestedPackage) |
|
|
|
|
|
if requestedPackage == "all" then |
|
|
|
|
|
|
|
|
updatePackage = (requestedPackage) -> |
|
|
|
|
|
if requestedPackage == "all" |
|
|
print("Updating everything...") |
|
|
print("Updating everything...") |
|
|
local locallyInstalledPackages = readFromLocalInstallFile() |
|
|
|
|
|
if not locallyInstalledPackages then |
|
|
|
|
|
io.stderr:write("Error while trying to read package names") |
|
|
|
|
|
|
|
|
locallyInstalledPackages = readFromLocalInstallFile() |
|
|
|
|
|
if not locallyInstalledPackages |
|
|
|
|
|
io.stderr\write("Error while trying to read package names") |
|
|
return |
|
|
return |
|
|
elseif locallyInstalledPackages[1] == -1 then |
|
|
|
|
|
|
|
|
elseif locallyInstalledPackages[1] == -1 |
|
|
table.remove(locallyInstalledPackages, 1) |
|
|
table.remove(locallyInstalledPackages, 1) |
|
|
end |
|
|
|
|
|
local done = false |
|
|
|
|
|
for localPackage in pairs(locallyInstalledPackages) do |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
done = false |
|
|
|
|
|
for localPackage in pairs(locallyInstalledPackages) |
|
|
installPackage(localPackage, nil, true) |
|
|
installPackage(localPackage, nil, true) |
|
|
done = true |
|
|
done = true |
|
|
end |
|
|
|
|
|
if not done then |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if not done |
|
|
print("No package has been installed so far.") |
|
|
print("No package has been installed so far.") |
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
else |
|
|
else |
|
|
installPackage(args[2], nil, true) |
|
|
installPackage(args[2], nil, true) |
|
|
end |
|
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
if args[1] == "list" then |
|
|
|
|
|
local tPacks = listPackages(args[2]) |
|
|
|
|
|
|
|
|
if args[1] == "list" |
|
|
|
|
|
tPacks = listPackages(args[2]) |
|
|
printPackages(tPacks) |
|
|
printPackages(tPacks) |
|
|
elseif args[1] == "info" then |
|
|
|
|
|
|
|
|
elseif args[1] == "info" |
|
|
provideInfo(args[2]) |
|
|
provideInfo(args[2]) |
|
|
elseif args[1] == "install" or args[1] == "add" then |
|
|
|
|
|
|
|
|
elseif args[1] == "install" or args[1] == "add" |
|
|
installPackage(args[2], args[3], false) |
|
|
installPackage(args[2], args[3], false) |
|
|
elseif args[1] == "update" or args[1] == "upgrade" then |
|
|
|
|
|
|
|
|
elseif args[1] == "update" or args[1] == "upgrade" |
|
|
updatePackage(args[2]) |
|
|
updatePackage(args[2]) |
|
|
elseif args[1] == "uninstall" or args[1] == "remove" then |
|
|
|
|
|
|
|
|
elseif args[1] == "uninstall" or args[1] == "remove" |
|
|
uninstallPackage(args[2]) |
|
|
uninstallPackage(args[2]) |
|
|
elseif args[1] == "copy" then |
|
|
|
|
|
|
|
|
elseif args[1] == "copy" |
|
|
copyPackage(args[2], args[3]) |
|
|
copyPackage(args[2], args[3]) |
|
|
else |
|
|
else |
|
|
printUsage() |
|
|
printUsage() |
|
|
return |
|
|
|
|
|
end |
|
|
|
|
|
|
|
|
return |