Browse Source

Adding initial spm program, clone of oppm

environments/production/deployments/2
Drew Short 7 years ago
parent
commit
cd29814d04
  1. 26
      gruntfile.js
  2. 475
      src/spm/main.lua

26
gruntfile.js

@ -41,17 +41,25 @@ module.exports = function (grunt) {
}); });
grunt.registerTask("minify-lua-modules", "minifies lua modules", function () { grunt.registerTask("minify-lua-modules", "minifies lua modules", function () {
var fs = require('fs');
var luamin = require('luamin');
const fs = require('fs');
const luamin = require('luamin');
const util = require('util');
grunt.file.expand({filter: 'isDirectory'}, "dist/*").forEach(function (dir) { grunt.file.expand({filter: 'isDirectory'}, "dist/*").forEach(function (dir) {
grunt.file.expand({filter: 'isFile'}, dir + "/*.lua").forEach(function (file) { grunt.file.expand({filter: 'isFile'}, dir + "/*.lua").forEach(function (file) {
var directory = file.substr(0, file.lastIndexOf('/'));
var file_name = file.substr(file.lastIndexOf('/') + 1, file.lastIndexOf('.'));
var lua = fs.readFileSync(file, 'utf8');
var minified = luamin.minify(lua);
var minified_file_name = file_name + '.min.lua';
fs.writeFileSync(directory + '/' + minified_file_name, minified);
console.log("Minified: " + file_name + ' -> ' + minified_file_name);
const directory = file.substr(0, file.lastIndexOf('/'));
const file_name = file.substr(file.lastIndexOf('/') + 1, file.lastIndexOf('.'));
const lua = fs.readFileSync(file, 'utf8');
const minified_contents = luamin.minify(lua);
const minified_file_name = file_name + '.min.lua';
const minified_file = directory + '/' + minified_file_name;
fs.writeFileSync(minified_file, minified_contents);
const file_stats = fs.statSync(file);
const minified_file_stats = fs.statSync(minified_file);
const saved_space = file_stats.size - minified_file_stats.size;
const saved_space_percent = (100 * (1 - minified_file_stats.size / file_stats.size)).toFixed(2);
console.log(util.format("Minified: %s: %f KB -> %s: %f KB. SAVED %d%% %d KB", file_name, file_stats.size / 1000, minified_file_name, minified_file_stats.size / 1000, saved_space_percent, saved_space / 1000));
}); });
}); });
}); });

475
src/spm/main.lua

@ -0,0 +1,475 @@
--[[
OpenPrograms package manager, browser and downloader, for easy access to many programs
Author: Vexatos
]]
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.")
return
end
local internet = require("internet")
local repoLocationConfig="https://raw.githubusercontent.com/OpenPrograms/openprograms.github.io/master/repos.cfg"
local args, options = shell.parse(...)
local function printUsage()
print("Sothr Package Manager, use this to browse through and download sothr packaged programs easily")
print("Usage:")
print("'spm list [-i]' to get a list of all the available program packages")
print("'spm list [-i] <filter>' to get a list of available packages containing the specified substring")
print(" -i: Only list already installed packages")
print("'spm info <package>' to get further information about a program package")
print("'spm install [-f] <package> [path]' to download a package to a directory on your system (or /usr by default)")
print("'spm update <package>' to update an already installed package")
print("'spm update all' to update every already installed package")
print("'spm uninstall <package>' to remove a package from your system")
print(" -f: Force creation of directories and overwriting of existing files.")
end
local function getContent(url)
local sContent = ""
local result, response = pcall(internet.request, url)
if not result then
return nil
end
for chunk in response do
sContent = sContent..chunk
end
return sContent
end
local function getRepos()
local 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.")
return -1
end
return serial.unserialize(sRepos)
end
local function getPackages(repo)
local success, sPackages = pcall(getContent,"https://raw.githubusercontent.com/"..repo.."/master/programs.cfg")
if not success or not sPackages then
return -1
end
return serial.unserialize(sPackages)
end
--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
return a:sub(i,i) < b:sub(i,i)
end
end
return #a < #b
end
local function downloadFile(url,path,force)
if options.f or force then
wget("-fq",url,path)
else
wget("-q",url,path)
end
end
local function readFromFile(fNum)
local path
if fNum == 1 then
path = "/etc/opdata.svd"
elseif fNum == 2 then
path = "/etc/oppm.cfg"
if not fs.exists(path) then
local tProcess = process.running()
path = fs.concat(fs.path(shell.resolve(tProcess)),"/etc/oppm.cfg")
end
end
if not fs.exists(fs.path(path)) then
fs.makeDirectory(fs.path(path))
end
if not fs.exists(path) then
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)
return
end
local sPacks = file:read("*a")
file:close()
return serial.unserialize(sPacks) or {-1}
end
local function saveToFile(tPacks)
local file,msg = io.open("/etc/opdata.svd","wb")
if not file then
io.stderr:write("Error while trying to save package names: "..msg)
return
end
local sPacks = serial.serialize(tPacks)
file:write(sPacks)
file:close()
end
local function listPackages(filter)
filter = filter or false
if filter then
filter = string.lower(filter)
end
local packages = {}
print("Receiving Package list...")
if not options.i then
local success, repos = pcall(getRepos)
if not success or repos==-1 then
io.stderr:write("Unable to connect to the Internet.\n")
return
elseif repos==nil then
print("Error while trying to receive repository list")
return
end
for _,j in pairs(repos) do
if j.repo then
print("Checking Repository "..j.repo)
local lPacks = getPackages(j.repo)
if lPacks==nil then
io.stderr:write("Error while trying to receive package list for " .. j.repo.."\n")
return
elseif type(lPacks) == "table" then
for k in pairs(lPacks) do
if not k.hidden then
table.insert(packages,k)
end
end
end
end
end
local lRepos = readFromFile(2)
if lRepos then
for _,j in pairs(lRepos.repos) do
for k in pairs(j) do
if not k.hidden then
table.insert(packages,k)
end
end
end
end
else
local lPacks = {}
local tPacks = readFromFile(1)
for i in pairs(tPacks) do
table.insert(lPacks,i)
end
packages = lPacks
end
if filter then
local lPacks = {}
for i,j in ipairs(packages) do
if (#j>=#filter) and string.find(j,filter,1,true)~=nil then
table.insert(lPacks,j)
end
end
packages = lPacks
end
table.sort(packages,compare)
return packages
end
local function printPackages(tPacks)
if tPacks==nil or not tPacks[1] then
print("No package matching specified filter found.")
return
end
term.clear()
local xRes,yRes = gpu.getResolution()
print("--OpenPrograms Package list--")
local xCur,yCur = term.getCursor()
for _,j in ipairs(tPacks) do
term.write(j.."\n")
yCur = yCur+1
if yCur>yRes-1 then
term.write("[Press any key to continue]")
local event = event.pull("key_down")
if event then
term.clear()
print("--OpenPrograms Package list--")
xCur,yCur = term.getCursor()
end
end
end
end
local function getInformation(pack)
local success, repos = pcall(getRepos)
if not success or repos==-1 then
io.stderr:write("Unable to connect to the Internet.\n")
return
end
for _,j in pairs(repos) do
if j.repo then
local lPacks = getPackages(j.repo)
if lPacks==nil then
io.stderr:write("Error while trying to receive package list for "..j.repo.."\n")
elseif type(lPacks) == "table" then
for k in pairs(lPacks) do
if k==pack then
return lPacks[k],j.repo
end
end
end
end
end
local lRepos = readFromFile(2)
if lRepos then
for i,j in pairs(lRepos.repos) do
for k in pairs(j) do
if k==pack then
return j[k],i
end
end
end
end
return nil
end
local function provideInfo(pack)
if not pack then
printUsage()
return
end
pack = string.lower(pack)
local info = getInformation(pack)
if not info then
print("Package does not exist")
return
end
local done = false
print("--Information about package '"..pack.."'--")
if info.name then
print("Name: "..info.name)
done = true
end
if info.description then
print("Description: "..info.description)
done = true
end
if info.authors then
print("Authors: "..info.authors)
done = true
end
if info.note then
print("Note: "..info.note)
done = true
end
if not done then
print("No information provided.")
end
end
local function installPackage(pack,path,update)
update = update or false
if not pack then
printUsage()
return
end
if not path and not update then
local lConfig = readFromFile(2)
path = lConfig.path or "/usr"
print("Installing package to "..path.."...")
elseif not update then
path = shell.resolve(path)
print("Installing package to "..path.."...")
end
pack = string.lower(pack)
local tPacks = readFromFile(1)
if not tPacks then
io.stderr:write("Error while trying to read local package names")
return
elseif tPacks[1]==-1 then
table.remove(tPacks,1)
end
local info,repo = getInformation(pack)
if not info then
print("Package does not exist")
return
end
if update then
print("Updating package "..pack)
path = nil
for i,j in pairs(info.files) do
for k,v in pairs(tPacks[pack]) do
if k==i then
path = string.gsub(fs.path(v),j.."/?$","/")
break
end
end
if path then
break
end
end
path = shell.resolve(string.gsub(path,"^/?","/"),nil)
end
if not update and fs.exists(path) then
if not fs.isDirectory(path) then
if options.f then
path = fs.concat(fs.path(path),pack)
fs.makeDirectory(path)
else
print("Path points to a file, needs to be a directory.")
return
end
end
elseif not update then
if options.f then
fs.makeDirectory(path)
else
print("Directory does not exist.")
return
end
end
if tPacks[pack] and (not update) then
print("Package has already been installed")
return
elseif not tPacks[pack] and update then
print("Package has not been installed.")
print("If it has, uninstall it manually and reinstall it.")
return
end
if update then
term.write("Removing old files...")
for i,j in pairs(tPacks[pack]) do
fs.remove(j)
end
term.write("Done.\n")
end
tPacks[pack] = {}
term.write("Installing Files...")
for i,j in pairs(info.files) do
local nPath
if string.find(j,"^//") then
local lPath = string.sub(j,2)
if not fs.exists(lPath) then
fs.makeDirectory(lPath)
end
nPath = fs.concat(lPath,string.gsub(i,".+(/.-)$","%1"),nil)
else
local lPath = fs.concat(path,j)
if not fs.exists(lPath) then
fs.makeDirectory(lPath)
end
nPath = fs.concat(path,j,string.gsub(i,".+(/.-)$","%1"),nil)
end
local success = pcall(downloadFile,"https://raw.githubusercontent.com/"..repo.."/"..i,nPath)
if success then
tPacks[pack][i] = nPath
end
end
if info.dependencies then
term.write("Done.\nInstalling Dependencies...")
for i,j in pairs(info.dependencies) do
local nPath
if string.find(j,"^//") then
nPath = string.sub(j,2)
else
nPath = fs.concat(path,j,string.gsub(i,".+(/.-)$","%1"),nil)
end
if string.lower(string.sub(i,1,4))=="http" then
local success = pcall(downloadFile,i,nPath)
if success then
tPacks[pack][i] = nPath
end
else
local depInfo = getInformation(string.lower(i))
if not depInfo then
term.write("\nDependency package "..i.." does not exist.")
end
installPackage(string.lower(i),fs.concat(path,j))
end
end
end
term.write("Done.\n")
saveToFile(tPacks)
print("Successfully installed package "..pack)
end
local function uninstallPackage(pack)
local info,repo = getInformation(pack)
if not info then
print("Package does not exist")
return
end
local tFiles = readFromFile(1)
if not tFiles then
io.stderr:write("Error while trying to read package names")
return
elseif tFiles[1]==-1 then
table.remove(tFiles,1)
end
if not tFiles[pack] then
print("Package has not been installed.")
print("If it has, you have to remove it manually.")
return
end
term.write("Removing package files...")
for i,j in pairs(tFiles[pack]) do
fs.remove(j)
end
term.write("Done\nRemoving references...")
tFiles[pack]=nil
saveToFile(tFiles)
term.write("Done.\n")
print("Successfully uninstalled package "..pack)
end
local function updatePackage(pack)
if pack=="all" then
print("Updating everything...")
local tFiles = readFromFile(1)
if not tFiles then
io.stderr:write("Error while trying to read package names")
return
elseif tFiles[1]==-1 then
table.remove(tFiles,1)
end
local done = false
for i in pairs(tFiles) do
installPackage(i,nil,true)
done = true
end
if not done then
print("No package has been installed so far.")
end
else
installPackage(args[2],nil,true)
end
end
if args[1] == "list" then
local tPacks = listPackages(args[2])
printPackages(tPacks)
elseif args[1] == "info" then
provideInfo(args[2])
elseif args[1] == "install" then
installPackage(args[2],args[3],false)
elseif args[1] == "update" then
updatePackage(args[2])
elseif args[1] == "uninstall" then
uninstallPackage(args[2])
else
printUsage()
return
end
Loading…
Cancel
Save